<template>
  <div class="container">
    <a-modal
      v-model:visible="visible"
      v-model:draggable="draggable"
      :title="title"
      @cancel="handleCancel"
      @before-ok="onBeforeOk"
    >
      <a-form
        ref="formRef"
        :label-col-props="{ span: 7 }"
        :wrapper-col-props="{ span: 17 }"
        :model="formData"
        class="form"
      >
        <a-spin dot :loading="loading">
          <a-form-item label="父菜单">
            <a-input v-model="formData.parentName" disabled />
          </a-form-item>

          <a-form-item label="菜单类型" field="type">
            <a-select
              v-model="formData.menuType"
              placeholder="菜单类型"
              disabled
            >
              <a-option value="0"
                ><icon-list />目录</a-option
              >
              <a-option value="1"
                ><icon-menu />菜单</a-option
              >
              <a-option value="2">
                <icon-play-arrow />按钮</a-option
              >
            </a-select>
          </a-form-item>

          <a-form-item
            label="资源名称"
            field="menuName"
            :validate-trigger="['change', 'input']"
            :rules="[
              {
                required: true,
                message: '请输入资源名称',
              },
              {
                maxLength: 15,
                message: '资源名称最多15个字符',
              },
              {
                minLength: 2,
                message: '资源名称最少2个字符',
              }
            ]"
          >
            <a-input v-model="formData.menuName" placeholder="如:用户管理"/>
          </a-form-item>

          <a-form-item
            v-if="formData.menuType !== '2'"
            label="路由标识"
            field="routeName"
            :validate-trigger="['change', 'input']"
            :rules="[
              {
                required: true,
                message:'请输入路由标识',
              },
              {
                maxLength: 20,
                message: '路由标识最多20个字符',
              },
              {
                minLength: 2,
                message: '路由标识最少2个字符',
              },
            ]"
          >
            <a-input v-model="formData.routeName" placeholder="如: userManager" />
          </a-form-item>

          <a-form-item
              v-if="formData.menuType !== '2'"
              label="路由地址"
              field="routePath"
              :validate-trigger="['change', 'input']"
              :rules="[
              {
                required: true,
                message:'请输入路由标识',
              },
              {
                maxLength: 20,
                message: '路由标识最多20个字符',
              },
              {
                minLength: 2,
                message: '路由标识最少2个字符',
              },
            ]"
          >
            <a-input v-model="formData.routePath" placeholder="如: user/manager" />
          </a-form-item>


          <a-form-item
            v-if="formData.menuType == '1'"
            label="页面地址"
            field="component"
            :validate-trigger="['change', 'input']"
            :rules="[
              {
                required: true,
                message:'请输入页面地址',
              },
              {
                minLength: 3,
                 message: '页面地址最少3个字符',
              },
            ]"
          >
            <a-input v-model="formData.component" placeholder="如:@/views/xxx/xxx.vue" />
          </a-form-item>


          <a-form-item
            v-if="formData.menuType !== '0'"
            label="接口地址"
            field="menuPath"
            :validate-trigger="['change', 'input']"
            :rules="[
              {
                minLength: 5,
                message: '接口地址最少5个字符',
              },
            ]"
          >
            <a-textarea
              v-model="formData.menuPath"
              placeholder="多个接口用 分号 ; 如:/user/delete;user/save"
              allow-clear
            />
          </a-form-item>

          <a-form-item
            label="权限标识"
            field="meta.perms"
            :validate-trigger="['change', 'input']"
            :rules="roleRules"
          >
            <a-input v-model="formData.meta.perm" placeholder="如:user:delete" />
          </a-form-item>

          <a-form-item
            v-if="formData.type !== '2'"
            label="菜单图标"
            field="meta.icon"
            :validate-trigger="['change', 'input']"
          >
            <a-input v-model="formData.meta.icon" placeholder="icon" />
          </a-form-item>

          <a-form-item label="排序" field="order">
            <a-input-number v-model="formData.sortCode" placeholder="order" />
          </a-form-item>

          <a-form-item
            v-show="false"
            v-if="isNew"
            label="父ID"
            field="parentId"
          >
            <a-input v-model="formData.parentId" placeholder="pid" />
          </a-form-item>

          <a-row v-if="formData.menuType !== '2'">
            <a-form-item>
              <a-col :span="5">
                <div>
                  <a-tooltip
                    content="是否开启授权访问"
                  >
                    <a-switch
                      v-model="formData.meta.requiresAuth"
                      type="round"
                    />
                  </a-tooltip>
                </div>
              </a-col>

              <a-col :span="5">
                <div>
                  <a-tooltip content="是否隐藏菜单">
                    <a-switch v-model="formData.meta.hideInMenu" type="round" />
                  </a-tooltip>
                </div>
              </a-col>
              <a-col :span="5">
                <div>
                  <a-tooltip content="开启tab-bar隐藏">
                    <a-switch v-model="formData.meta.noAffix" type="round" />
                  </a-tooltip>
                </div>
              </a-col>
              <a-col :span="5">
                <div>
                  <a-tooltip
                    content="是否开启页面缓存"
                  >
                    <a-switch
                      v-model="formData.meta.ignoreCache"
                      type="round"
                    />
                  </a-tooltip>
                </div>
              </a-col>

              <a-col :span="4">
                <div>
                  <a-tooltip
                    content="左侧菜单中显示单项"
                  >
                    <a-switch
                      v-model="formData.meta.hideChildrenInMenu"
                      type="round"
                    />
                  </a-tooltip>
                </div>
              </a-col>
            </a-form-item>
          </a-row>
        </a-spin>
      </a-form>
    </a-modal>
  </div>
</template>

<script lang="ts">
import {defineComponent, ref, watch} from 'vue';
import {FormInstance} from '@arco-design/web-vue/es/form';
import useLoading from '@/hooks/loading';
import {useI18n} from 'vue-i18n';
import {addForm, detail, editForm} from '@/api/menu';
import {Message} from '@arco-design/web-vue';

const formModel = () => {
    return {
      id: '',
      menuName: null,
      menuType: '0',
      menuPath:null,
      routeName:null,
      routePath:'',
      sortCode: 0,
      parentId: '0',
      parentName: '',
      component:'',
      perms:null,
      meta: {
        perm: '',
        requiresAuth: true,
        icon: '',
        locale: '',
        hideInMenu: false,
        hideChildrenInMenu: false,
        activeMenu: '',
        order: 1,
        noAffix: false,
        ignoreCache: false,
      }
    };
  };

  export default defineComponent({
    setup(props, context) {
      const { t } = useI18n();
      const formData = ref(formModel());
      const formRef = ref<FormInstance>();
      const { setLoading } = useLoading();
      const operate = ref<number>();
      const isNew = ref<boolean>(false);
      const onBeforeOk = async (done: (arg: boolean) => void) => {
        const res = await formRef.value?.validate();
        if (!res) {
          try {
            setLoading(true);
            if (isNew.value) {
              await addForm(formData.value);
            } else {
              await editForm(formData.value);
            }
            Message.success(t('request.ok'));
            context.emit('ok');
          } catch (e) {
            return done(false);
          } finally {
            setLoading(false);
          }
        }
        return done(!res);
      };


      watch(
          () => formData.value.menuName,
          (newValue:any, old) => {
            formData.value.meta.locale = newValue
          },
          { deep: true }
      )
      watch(
          () => formData.value.meta.perm,
          (newValue:any, old) => {
            formData.value.perms = newValue
          },
          { deep: true }
      )

      const roleRules = [
        {
          validator: (value: string, cb: (arg0: string) => void) => {
            return new Promise<void>((resolve) => {
              if (
                formData.value.meta?.requiresAuth &&
                formData.value.meta.perm?.length === 0
              ) {
                cb(t('请输入权限标识'));
              }
              resolve();
            });
          },
        },
      ];

      const localeRules = [
        {
          validator: (value: string, cb: (arg0: string) => void) => {
            return new Promise<void>((resolve) => {
              if (!formData.value.meta.locale) {
                cb(t('form.menu.meta.locale.required.errMsg'));
              }
              resolve();
            });
          },
        },
      ];

      const iconRules = [
        {
          validator: (value: string, cb: (arg0: string) => void) => {
            return new Promise<void>((resolve) => {
              if (!formData.value.meta.icon) {
                cb(t('form.menu.meta.icon.required.errMsg'));
              }
              resolve();
            });
          },
        },
      ];

      const reset = async () => {
        formData.value = formModel();
        await formRef.value?.resetFields();
      };
      return {
        formRef,
        reset,
        operate,
        formData,
        isNew,
        roleRules,
        iconRules,
        localeRules,
        t,
        onBeforeOk,
      };
    },
    data() {
      return {
        visible: false,
        draggable: true,
        title: '',
        loading: false,
      };
    },
    methods: {
      addForm(pid: string, type: number, parentName: string) {
        this.reset();
        this.visible = true;
        this.isNew = true;
        this.title = '新增菜单';
        this.formData.parentId=pid;
        this.formData.menuType = type.toString();
        this.formData.parentName = parentName;
      },

      async editForm(id: string) {
        await this.reset();
        this.visible = true;
        this.isNew = false;
        this.title = '编辑菜单';
        const {data} = await detail(id);
        data.meta = JSON.parse(data.meta);
        this.formData = data
      },
      setLoading(loading: boolean) {
        this.loading = loading;
      },
      handleCancel() {
        this.reset();
        this.visible = false;
        this.isNew = true;
      },
    },
  });
</script>

<style scoped lang="less">
  .container {
    padding: 20px;

    .keep-margin {
      margin-bottom: 20px;
    }
  }

  .form {
    width: 420px;
  }
</style>
